package com.game.logic.items.account;

import com.coment.cfg.luban.GuaranteeCfg;
import com.coment.cfg.luban.PoolCfg;
import com.coment.cfg.luban.Tables;
import com.coment.cfg.luban.constant.CurrencyType;
import com.coment.cfg.luban.constant.ItemsType;
import com.coment.message.DrawResult;
import com.game.framework.ActorManager;
import com.game.logic.core.comment.Bonus;
import com.game.logic.drawCards.DrawCardsServiceImpl;
import com.game.logic.items.ItemsService;
import com.coment.message.account.PayInfo;
import com.game.logic.items.bonus.BonusService;
import com.game.dao.user.UserPlayInfoDao;
import com.coment.po.UserDrawInfo;
import com.game.dao.user.draw.UserDrawInfoDao;
import com.xs.action.exection.ActionException;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;


@Slf4j
@Service
public class UserAccountService {
    @Resource
    private UserPlayInfoDao userPlayInfoDao;
    @Lazy
    @Resource
    private ItemsService itemsService;
    @Resource
    private UserDrawInfoDao userDrawInfoDao;
    private static final List<GuaranteeCfg> listOfGuaranteeCfg;

    static {
        listOfGuaranteeCfg = new ArrayList<>(Tables.cfg.get_tbguaranteecfg().getDataList().stream().filter(guaranteeCfg -> guaranteeCfg.type == 1).toList());
        listOfGuaranteeCfg.sort((o1, o2) -> o2.need - o1.need);
    }

    public List<DrawResult> openCardPackage(Integer userInfoId, Integer num) {
        String rolesId = userPlayInfoDao.findByUserInfoIdOrCreate(userInfoId).getRecentlyPlayedRolesId();
        if (rolesId == null) {
            throw new ActionException("玩家未加入房间" + userInfoId);
        }

        PayInfo pay = null;
        try {
            pay = ActorManager.ask(
                    UserAccountActor.class,
                    new PayInfo(userInfoId, CurrencyType.card, num, "使用卡包"),
                    userInfoId
            );
        } catch (Exception e) {
            log.error("Failed to pay for userInfoId: {}", userInfoId, e);
            throw new ActionException("支付失败");
        }

        if (!pay.isPay()) {
            throw new ActionException("支付失败" + pay.getMessage());
        }

        UserDrawInfo userDrawInfo = userDrawInfoDao.findOrCreateById(userInfoId);
        int drawCount = userDrawInfo.getDrawCount();

        List<DrawResult> res = new ArrayList<>();


        while (res.size() < num) {
            List<DrawResult> aMinimumGuarantee = getAMinimumGuarantee(userInfoId, userDrawInfo);
            if (!aMinimumGuarantee.isEmpty()) {
                res.addAll(aMinimumGuarantee);
                drawCount++;
                continue;
            }

            PoolCfg drawSingle = DrawCardsServiceImpl.cardPoolCfg.drawSingle();
            Integer value = drawSingle.value;
            List<DrawResult> drawResults = itemsService.obtainItems(userInfoId, ItemsType.Bonus, value);
            if (!drawResults.isEmpty()) {
                drawCount++;
                res.addAll(drawResults);
            }
        }
        userDrawInfo.setDrawCount(drawCount);
        userDrawInfoDao.save(userDrawInfo);
        return res;
    }

    private List<DrawResult> getAMinimumGuarantee(Integer userInfoId, UserDrawInfo userDrawInfo) {
        StringBuilder sb = new StringBuilder();

        int drawCount = userDrawInfo.getDrawCount();
        List<DrawResult> minimumGuaranteeResults = new ArrayList<>();
        for (GuaranteeCfg guaranteeCfg : listOfGuaranteeCfg) {
            int drawCountAfter = drawCount++;         // 计算抽卡后次数

            // 计算抽卡前和抽卡后相对于保底阈值的倍数
            int timesAfter = drawCountAfter / guaranteeCfg.need;

            if (userDrawInfo.drawTimes == null) {
                userDrawInfo.drawTimes = new HashMap<>();
            }

            // 如果倍数增加，说明触发了保底

            Integer drawTimesOrDefault = userDrawInfo.drawTimes.getOrDefault(guaranteeCfg.need, 0);
            int guaranteeTriggeredTimes = timesAfter - drawTimesOrDefault;

            if (guaranteeTriggeredTimes > 0) {
                drawTimesOrDefault++;
                userDrawInfo.drawTimes.put(guaranteeCfg.need, drawTimesOrDefault);

                Integer bonusId = guaranteeCfg.obtain;
                sb.append("触发保底--")
                        .append("抽卡次数: ")
                        .append(drawCountAfter)
                        .append("礼包id: ")
                        .append(bonusId)
                        .append("累计触发保底次数")
                        .append(drawTimesOrDefault)
                        .append("未使用的保底次数")
                        .append(timesAfter - drawTimesOrDefault)
                ;

                Bonus<Integer> integerBonus = BonusService.bonusPoll.get(bonusId);
                List<Integer> bonusValue = integerBonus.getBonusValue();
                int group = integerBonus.getGroup();

                for (Integer value : bonusValue) {
                    minimumGuaranteeResults.addAll(itemsService.obtainItems(userInfoId, group, value));
                }
            }


            if (!sb.isEmpty()) {
                log.info("保底结果: {}", sb);
                return minimumGuaranteeResults;
            }
        }

        return minimumGuaranteeResults;
    }
}
